[ty] Respect type variables in top/bottom materializations of invariant generics - #28072
[ty] Respect type variables in top/bottom materializations of invariant generics#28072sharkdp wants to merge 11 commits into
Conversation
e8d39af to
55aa8f4
Compare
Typing conformance resultsNo changes detected ✅Current numbersThe percentage of diagnostics emitted that were expected errors held steady at 97.79%. The percentage of expected errors that received a diagnostic held steady at 94.33%. The number of fully passing files held steady at 112/136. |
Memory usage reportSummary
Significant changesClick to expand detailed breakdownprefect
trio
sphinx
|
|
| Lint rule | Added | Removed | Changed |
|---|---|---|---|
invalid-argument-type |
18 | 0 | 12 |
invalid-return-type |
8 | 0 | 6 |
invalid-assignment |
4 | 0 | 9 |
invalid-yield |
3 | 0 | 0 |
unsound-return-statement |
2 | 1 | 0 |
no-matching-overload |
1 | 1 | 0 |
type-assertion-failure |
2 | 0 | 0 |
redundant-cast |
0 | 1 | 0 |
unresolved-attribute |
1 | 0 | 0 |
| Total | 39 | 3 | 27 |
Raw diff (69 changes)
anyio (https://github.com/agronholm/anyio)
+ src/anyio/itertools.py:116:13 error[invalid-assignment] Object of type `Top[_TeeState[Unknown]]` is not assignable to attribute `_state` of type `_TeeState[T@_TeeAsyncIterator]`
+ src/anyio/itertools.py:117:13 error[invalid-assignment] Object of type `Top[_TeeLink[Unknown]]` is not assignable to attribute `_link` of type `_TeeLink[T@_TeeAsyncIterator]`
archinstall (https://github.com/archlinux/archinstall)
- archinstall/tui/result.py:71:10 warning[redundant-cast] Value is already of type `list[ValueT@Result]`
cki-lib (https://gitlab.com/cki-project/cki-lib)
+ cki_lib/misc.py:68:24 error[invalid-yield] Yield type `object` does not match annotated yield type `T@flattened`
core (https://github.com/home-assistant/core)
+ homeassistant/components/datadog/__init__.py:85:31 error[invalid-argument-type] Argument to bound method `EventBus.async_listen` is incorrect: Expected `EventType[Mapping[str, Any]] | str`, found `EventType[EventStateChangedData]`
+ homeassistant/components/influxdb/__init__.py:595:35 error[invalid-argument-type] Argument to bound method `EventBus.async_listen` is incorrect: Expected `EventType[Mapping[str, Any]] | str`, found `EventType[EventStateChangedData]`
+ homeassistant/components/statsd/__init__.py:91:21 error[invalid-argument-type] Argument to bound method `EventBus.listen` is incorrect: Expected `EventType[Mapping[str, Any]] | str`, found `EventType[EventStateChangedData]`
- homeassistant/core.py:2482:17 error[invalid-argument-type] Argument to bound method `EventBus.async_fire_internal` is incorrect: Expected `EventType[EventStateReportedData | dict[str, str | datetime | State | None]] | str`, found `EventType[EventStateReportedData]`
+ homeassistant/core.py:2482:17 error[invalid-argument-type] Argument to bound method `EventBus.async_fire_internal` is incorrect: Expected `EventType[dict[str, str | datetime | State | None]] | str`, found `EventType[EventStateReportedData]`
+ homeassistant/helpers/device_registry.py:2941:13 error[invalid-argument-type] Argument to bound method `EventBus.async_fire_internal` is incorrect: Expected `EventType[_EventDeviceRegistryUpdatedData_Update] | str`, found `EventType[EventDeviceRegistryUpdatedData]`
+ homeassistant/helpers/device_registry.py:3432:43 error[invalid-argument-type] Argument to bound method `EventBus.async_fire_internal` is incorrect: Expected `EventType[_EventDeviceRegistryUpdatedData_Create | _EventDeviceRegistryUpdatedData_Update] | str`, found `EventType[EventDeviceRegistryUpdatedData]`
+ homeassistant/helpers/device_registry.py:3615:43 error[invalid-argument-type] Argument to bound method `EventBus.async_fire_internal` is incorrect: Expected `EventType[_EventDeviceRegistryUpdatedData_Create | _EventDeviceRegistryUpdatedData_Update] | str`, found `EventType[EventDeviceRegistryUpdatedData]`
+ homeassistant/helpers/device_registry.py:4104:13 error[invalid-argument-type] Argument to bound method `EventBus.async_fire_internal` is incorrect: Expected `EventType[_EventDeviceRegistryUpdatedData_Remove] | str`, found `EventType[EventDeviceRegistryUpdatedData]`
+ homeassistant/helpers/device_registry.py:4135:13 error[invalid-argument-type] Argument to bound method `EventBus.async_fire_internal` is incorrect: Expected `EventType[_EventDeviceRegistryUpdatedData_Remove] | str`, found `EventType[EventDeviceRegistryUpdatedData]`
+ homeassistant/helpers/entity_registry.py:1616:13 error[invalid-argument-type] Argument to bound method `EventBus.async_fire_internal` is incorrect: Expected `EventType[_EventEntityRegistryUpdatedData_CreateRemove] | str`, found `EventType[EventEntityRegistryUpdatedData]`
+ homeassistant/helpers/entity_registry.py:1664:13 error[invalid-argument-type] Argument to bound method `EventBus.async_fire_internal` is incorrect: Expected `EventType[_EventEntityRegistryUpdatedData_CreateRemove] | str`, found `EventType[EventEntityRegistryUpdatedData]`
+ homeassistant/helpers/entity_registry.py:2014:43 error[invalid-argument-type] Argument to bound method `EventBus.async_fire_internal` is incorrect: Expected `EventType[_EventEntityRegistryUpdatedData_Update] | str`, found `EventType[EventEntityRegistryUpdatedData]`
+ homeassistant/helpers/floor_registry.py:225:13 error[invalid-argument-type] Argument to bound method `EventBus.async_fire_internal` is incorrect: Expected `EventType[_EventFloorRegistryUpdatedData_Create_Remove_Update] | str`, found `EventType[EventFloorRegistryUpdatedData]`
+ homeassistant/helpers/floor_registry.py:238:13 error[invalid-argument-type] Argument to bound method `EventBus.async_fire_internal` is incorrect: Expected `EventType[_EventFloorRegistryUpdatedData_Create_Remove_Update] | str`, found `EventType[EventFloorRegistryUpdatedData]`
+ homeassistant/helpers/floor_registry.py:280:13 error[invalid-argument-type] Argument to bound method `EventBus.async_fire_internal` is incorrect: Expected `EventType[_EventFloorRegistryUpdatedData_Create_Remove_Update] | str`, found `EventType[EventFloorRegistryUpdatedData]`
+ homeassistant/helpers/floor_registry.py:307:13 error[invalid-argument-type] Argument to bound method `EventBus.async_fire_internal` is incorrect: Expected `EventType[_EventFloorRegistryUpdatedData_Reorder] | str`, found `EventType[EventFloorRegistryUpdatedData]`
- homeassistant/scripts/benchmark/__init__.py:143:29 error[invalid-argument-type] Argument to bound method `EventBus.async_fire` is incorrect: Expected `EventType[EventStateChangedData | dict[str, str | State]] | str`, found `EventType[EventStateChangedData]`
+ homeassistant/scripts/benchmark/__init__.py:143:29 error[invalid-argument-type] Argument to bound method `EventBus.async_fire` is incorrect: Expected `EventType[dict[str, str | State]] | str`, found `EventType[EventStateChangedData]`
- homeassistant/scripts/benchmark/__init__.py:176:29 error[invalid-argument-type] Argument to bound method `EventBus.async_fire` is incorrect: Expected `EventType[EventStateChangedData | dict[str, str | State]] | str`, found `EventType[EventStateChangedData]`
+ homeassistant/scripts/benchmark/__init__.py:176:29 error[invalid-argument-type] Argument to bound method `EventBus.async_fire` is incorrect: Expected `EventType[dict[str, str | State]] | str`, found `EventType[EventStateChangedData]`
- homeassistant/scripts/benchmark/__init__.py:214:29 error[invalid-argument-type] Argument to bound method `EventBus.async_fire` is incorrect: Expected `EventType[EventStateChangedData | dict[str, str | State]] | str`, found `EventType[EventStateChangedData]`
+ homeassistant/scripts/benchmark/__init__.py:214:29 error[invalid-argument-type] Argument to bound method `EventBus.async_fire` is incorrect: Expected `EventType[dict[str, str | State]] | str`, found `EventType[EventStateChangedData]`
discord.py (https://github.com/Rapptz/discord.py)
+ discord/ext/commands/cog.py:461:32 error[invalid-yield] Yield type `Top[Command[Unknown, (...), Any]]` does not match annotated yield type `Command[Self@walk_commands, (...), Any]`
+ discord/ext/commands/core.py:1455:28 error[invalid-yield] Yield type `Top[Command[Unknown, (...), Any]]` does not match annotated yield type `Command[CogT@GroupMixin, (...), Any]`
+ discord/ext/commands/core.py:1499:16 error[invalid-return-type] Return type does not match returned value: expected `Command[CogT@GroupMixin, (...), Any] | None`, found `Top[Command[Unknown, (...), Any]] | Unknown`
meson (https://github.com/mesonbuild/meson)
+ mesonbuild/modules/hotdoc.py:61:12 error[invalid-return-type] Return type does not match returned value: expected `list[_T@ensure_list]`, found `(_T@ensure_list & Top[list[Unknown]]) | list[_T@ensure_list]`
+ mesonbuild/utils/universal.py:1912:12 error[invalid-return-type] Return type does not match returned value: expected `list[_T@typeslistify]`, found `(_T@typeslistify & Top[list[Unknown]]) | Top[list[Unknown & _T@typeslistify]]`
mkdocs (https://github.com/mkdocs/mkdocs)
+ mkdocs/config/config_options.py:219:20 error[invalid-return-type] Return type does not match returned value: expected `list[T@ListOfItems]`, found `Top[list[Unknown]] & ~AlwaysTruthy`
optuna (https://github.com/optuna/optuna)
- optuna/storages/_rdb/alembic/versions/v1.3.0.a.py:63:59 error[invalid-argument-type] Argument to function `loads` is incorrect: Expected `str | bytes | bytearray`, found `Column[str]`
+ optuna/storages/_rdb/alembic/versions/v1.3.0.a.py:63:59 error[invalid-argument-type] Argument to function `loads` is incorrect: Expected `str | bytes | bytearray`, found `Column[Unknown]`
- optuna/storages/_rdb/alembic/versions/v3.0.0.a.py:158:13 error[invalid-assignment] Object of type `str` is not assignable to attribute `distribution_json` of type `Column[str]`
+ optuna/storages/_rdb/alembic/versions/v3.0.0.a.py:158:13 error[invalid-assignment] Object of type `str` is not assignable to attribute `distribution_json` of type `Column[Unknown]`
- optuna/storages/_rdb/alembic/versions/v3.0.0.a.py:159:17 error[invalid-argument-type] Argument to function `migrate_new_distribution` is incorrect: Expected `str`, found `Column[str]`
+ optuna/storages/_rdb/alembic/versions/v3.0.0.a.py:159:17 error[invalid-argument-type] Argument to function `migrate_new_distribution` is incorrect: Expected `str`, found `Column[Unknown]`
- optuna/storages/_rdb/alembic/versions/v3.0.0.a.py:187:13 error[invalid-assignment] Object of type `str` is not assignable to attribute `distribution_json` of type `Column[str]`
+ optuna/storages/_rdb/alembic/versions/v3.0.0.a.py:187:13 error[invalid-assignment] Object of type `str` is not assignable to attribute `distribution_json` of type `Column[Unknown]`
- optuna/storages/_rdb/alembic/versions/v3.0.0.a.py:188:17 error[invalid-argument-type] Argument to function `restore_old_distribution` is incorrect: Expected `str`, found `Column[str]`
+ optuna/storages/_rdb/alembic/versions/v3.0.0.a.py:188:17 error[invalid-argument-type] Argument to function `restore_old_distribution` is incorrect: Expected `str`, found `Column[Unknown]`
- optuna/storages/_rdb/alembic/versions/v3.0.0.c.py:128:25 error[invalid-assignment] Object of type `Column[float]` is not assignable to `float`
+ optuna/storages/_rdb/alembic/versions/v3.0.0.c.py:128:25 error[invalid-assignment] Object of type `Column[Unknown]` is not assignable to `float`
- optuna/storages/_rdb/alembic/versions/v3.0.0.d.py:132:25 error[invalid-assignment] Object of type `Column[float]` is not assignable to `float`
+ optuna/storages/_rdb/alembic/versions/v3.0.0.d.py:132:25 error[invalid-assignment] Object of type `Column[Unknown]` is not assignable to `float`
- optuna/storages/_rdb/storage.py:342:17 error[invalid-assignment] Invalid assignment to data descriptor attribute `value_json` on type `StudyUserAttributeModel`: Argument type `MappedColumn[Any] | Column[str]` does not satisfy upper bound `Mapped[Any]` of type variable `Self`
+ optuna/storages/_rdb/storage.py:342:17 error[invalid-assignment] Invalid assignment to data descriptor attribute `value_json` on type `StudyUserAttributeModel`: Argument type `MappedColumn[Any] | Column[Unknown]` does not satisfy upper bound `Mapped[Any]` of type variable `Self`
- optuna/storages/_rdb/storage.py:354:17 error[invalid-assignment] Invalid assignment to data descriptor attribute `value_json` on type `StudySystemAttributeModel`: Argument type `MappedColumn[Any] | Column[str]` does not satisfy upper bound `Mapped[Any]` of type variable `Self`
+ optuna/storages/_rdb/storage.py:354:17 error[invalid-assignment] Invalid assignment to data descriptor attribute `value_json` on type `StudySystemAttributeModel`: Argument type `MappedColumn[Any] | Column[Unknown]` does not satisfy upper bound `Mapped[Any]` of type variable `Self`
- optuna/storages/_rdb/storage.py:368:16 error[invalid-return-type] Return type does not match returned value: expected `str`, found `Any | Column[str]`
+ optuna/storages/_rdb/storage.py:368:16 error[invalid-return-type] Return type does not match returned value: expected `str`, found `Any | Column[Unknown]`
- optuna/storages/_rdb/storage.py:382:48 error[invalid-argument-type] Argument to function `loads` is incorrect: Expected `str | bytes | bytearray`, found `Any | Column[str]`
+ optuna/storages/_rdb/storage.py:382:48 error[invalid-argument-type] Argument to function `loads` is incorrect: Expected `str | bytes | bytearray`, found `Any | Column[Unknown]`
- optuna/storages/_rdb/storage.py:384:16 error[invalid-return-type] Return type does not match returned value: expected `dict[str, Any]`, found `dict[Any | Column[str], Any]`
+ optuna/storages/_rdb/storage.py:384:16 error[invalid-return-type] Return type does not match returned value: expected `dict[str, Any]`, found `dict[Any | Column[Unknown], Any]`
- optuna/storages/_rdb/storage.py:391:50 error[invalid-argument-type] Argument to function `loads` is incorrect: Expected `str | bytes | bytearray`, found `Any | Column[str]`
+ optuna/storages/_rdb/storage.py:391:50 error[invalid-argument-type] Argument to function `loads` is incorrect: Expected `str | bytes | bytearray`, found `Any | Column[Unknown]`
- optuna/storages/_rdb/storage.py:393:16 error[invalid-return-type] Return type does not match returned value: expected `dict[str, Any]`, found `dict[Any | Column[str], Any]`
+ optuna/storages/_rdb/storage.py:393:16 error[invalid-return-type] Return type does not match returned value: expected `dict[str, Any]`, found `dict[Any | Column[Unknown], Any]`
- optuna/storages/_rdb/storage.py:401:48 error[invalid-argument-type] Argument to function `loads` is incorrect: Expected `str | bytes | bytearray`, found `Any | Column[str]`
+ optuna/storages/_rdb/storage.py:401:48 error[invalid-argument-type] Argument to function `loads` is incorrect: Expected `str | bytes | bytearray`, found `Any | Column[Unknown]`
- optuna/storages/_rdb/storage.py:403:16 error[invalid-return-type] Return type does not match returned value: expected `dict[str, Any]`, found `dict[Any | Column[str], Any]`
+ optuna/storages/_rdb/storage.py:403:16 error[invalid-return-type] Return type does not match returned value: expected `dict[str, Any]`, found `dict[Any | Column[Unknown], Any]`
- optuna/storages/_rdb/storage.py:411:50 error[invalid-argument-type] Argument to function `loads` is incorrect: Expected `str | bytes | bytearray`, found `Any | Column[str]`
+ optuna/storages/_rdb/storage.py:411:50 error[invalid-argument-type] Argument to function `loads` is incorrect: Expected `str | bytes | bytearray`, found `Any | Column[Unknown]`
- optuna/storages/_rdb/storage.py:413:16 error[invalid-return-type] Return type does not match returned value: expected `dict[str, Any]`, found `dict[Any | Column[str], Any]`
+ optuna/storages/_rdb/storage.py:413:16 error[invalid-return-type] Return type does not match returned value: expected `dict[str, Any]`, found `dict[Any | Column[Unknown], Any]`
- optuna/storages/_rdb/storage.py:645:21 error[invalid-argument-type] Argument to function `json_to_distribution` is incorrect: Expected `str`, found `Any | Column[str]`
+ optuna/storages/_rdb/storage.py:645:21 error[invalid-argument-type] Argument to function `json_to_distribution` is incorrect: Expected `str`, found `Any | Column[Unknown]`
- optuna/storages/_rdb/storage.py:668:16 error[invalid-return-type] Return type does not match returned value: expected `float`, found `Any | Column[float]`
+ optuna/storages/_rdb/storage.py:668:16 error[invalid-return-type] Return type does not match returned value: expected `float`, found `Any | Column[Unknown]`
- optuna/storages/_rdb/storage.py:716:13 error[invalid-assignment] Invalid assignment to data descriptor attribute `value` on type `TrialValueModel`: Argument type `MappedColumn[Any] | Column[float]` does not satisfy upper bound `Mapped[Any]` of type variable `Self`
+ optuna/storages/_rdb/storage.py:716:13 error[invalid-assignment] Invalid assignment to data descriptor attribute `value` on type `TrialValueModel`: Argument type `MappedColumn[Any] | Column[Unknown]` does not satisfy upper bound `Mapped[Any]` of type variable `Self`
- optuna/storages/_rdb/storage.py:755:13 error[invalid-assignment] Invalid assignment to data descriptor attribute `intermediate_value` on type `TrialIntermediateValueModel`: Argument type `MappedColumn[Any] | Column[float]` does not satisfy upper bound `Mapped[Any]` of type variable `Self`
+ optuna/storages/_rdb/storage.py:755:13 error[invalid-assignment] Invalid assignment to data descriptor attribute `intermediate_value` on type `TrialIntermediateValueModel`: Argument type `MappedColumn[Any] | Column[Unknown]` does not satisfy upper bound `Mapped[Any]` of type variable `Self`
- optuna/storages/_rdb/storage.py:1211:13 error[invalid-assignment] Invalid assignment to data descriptor attribute `library_version` on type `VersionInfoModel`: Argument type `MappedColumn[Any] | Column[str]` does not satisfy upper bound `Mapped[Any]` of type variable `Self`
+ optuna/storages/_rdb/storage.py:1211:13 error[invalid-assignment] Invalid assignment to data descriptor attribute `library_version` on type `VersionInfoModel`: Argument type `MappedColumn[Any] | Column[Unknown]` does not satisfy upper bound `Mapped[Any]` of type variable `Self`
pandas-stubs (https://github.com/pandas-dev/pandas-stubs)
+ tests/test_pandas.py:525:11 error[type-assertion-failure] Type `ndarray[tuple[int], dtype[numpy.bool[builtins.bool]]]` does not match asserted type `ndarray[tuple[Any, ...], dtype[numpy.bool[builtins.bool]]]`
+ tests/test_pandas.py:526:11 error[type-assertion-failure] Type `ndarray[tuple[int], dtype[numpy.bool[builtins.bool]]]` does not match asserted type `ndarray[tuple[Any, ...], dtype[numpy.bool[builtins.bool]]]`
prefect (https://github.com/PrefectHQ/prefect)
- src/integrations/prefect-redis/tests/test_tasks.py:52:12 warning[unsound-return-statement] Unsound return statement: `Unknown` is not a subtype of `str`
+ src/prefect/_internal/states.py:239:16 error[invalid-return-type] Return type does not match returned value: expected `State[R@return_value_to_state_sync]`, found `R@return_value_to_state_sync & Top[State[Unknown]]`
+ src/prefect/futures.py:252:13 error[invalid-assignment] Object of type `R@PrefectConcurrentFuture & Top[State[Unknown]]` is not assignable to attribute `_final_state` of type `State[R@PrefectConcurrentFuture] | None`
+ src/prefect/futures.py:270:17 error[invalid-assignment] Object of type `R@PrefectConcurrentFuture & Top[State[Unknown]]` is not assignable to attribute `_final_state` of type `State[R@PrefectConcurrentFuture] | None`
- src/prefect/futures.py:277:19 error[no-matching-overload] No overload of bound method `State.result` matches arguments
+ src/prefect/futures.py:277:19 error[unresolved-attribute] Attribute `result` is not defined on `None` in union `State[R@PrefectConcurrentFuture] | None`
+ src/prefect/input/run_input.py:890:16 error[invalid-return-type] Return type does not match returned value: expected `GetAutomaticInputHandler[T@receive_input] | GetInputHandler[R@receive_input]`, found `Top[GetAutomaticInputHandler[Unknown]]`
+ src/prefect/server/database/query_components.py:577:13 warning[unsound-return-statement] Unsound return statement: `Select[tuple[Unknown, datetime]]` is not a subtype of `Select[tuple[datetime, datetime]]`
+ src/prefect/states.py:369:16 error[invalid-return-type] Return type does not match returned value: expected `State[R@return_value_to_state]`, found `R@return_value_to_state & Top[State[Unknown]]`
+ src/prefect/task_engine.py:628:34 error[invalid-argument-type] Argument to bound method `SyncTaskRunEngine.handle_retry` is incorrect: Expected `Exception | State[R@SyncTaskRunEngine]`, found `R@SyncTaskRunEngine & Top[State[Unknown]]`
+ src/prefect/task_engine.py:1253:40 error[invalid-argument-type] Argument to bound method `AsyncTaskRunEngine.handle_retry` is incorrect: Expected `Exception | State[R@AsyncTaskRunEngine]`, found `R@AsyncTaskRunEngine & Top[State[Unknown]]`
scrapy (https://github.com/scrapy/scrapy)
+ scrapy/utils/defer.py:392:16 error[invalid-return-type] Return type does not match returned value: expected `Deferred[_T@deferred_from_coro] | _T2@deferred_from_coro`, found `(Awaitable[_T@deferred_from_coro] & Top[Deferred[Unknown]]) | (_T2@deferred_from_coro & Top[Deferred[Unknown]])`
+ scrapy/utils/defer.py:571:41 error[invalid-argument-type] Argument to function `maybe_deferred_to_future` is incorrect: Expected `Deferred[_T@ensure_awaitable]`, found `(_T@ensure_awaitable & Top[Deferred[Unknown]]) | (Awaitable[_T@ensure_awaitable] & Top[Deferred[Unknown]])`
streamlit (https://github.com/streamlit/streamlit)
+ lib/streamlit/runtime/caching/cache_data_api.py:831:20 warning[unsound-return-statement] Unsound return statement: `Any & Top[CachedResult[Unknown]]` is not a subtype of `CachedResult[R@DataCache]`
tornado (https://github.com/tornadoweb/tornado)
+ tornado/concurrent.py:170:9 error[no-matching-overload] No overload of function `future_add_done_callback` matches arguments
Merging this PR will degrade performance by 23.28%
|
| Mode | Benchmark | BASE |
HEAD |
Efficiency | |
|---|---|---|---|---|---|
| ❌ | Simulation | ty_micro[invariant_generic_return_union] |
198.7 ms | 259 ms | -23.28% |
Tip
Investigate this regression with the CodSpeed MCP and your agent.
Comparing codex/invariant-typevar-materializations (88059dd) with main (c0b78da)
Footnotes
-
84 benchmarks were skipped, so the baseline results were used instead. If they were deleted from the codebase, click here and archive them to remove them from the performance reports. ↩
Validate possible overlap against TypeVar bounds and constraints, while retaining incompatible union alternatives so inference can still report argument errors. Add coverage for bounded and constrained nested type variables. Compare fixed ParamSpecs directly with materialization endpoints and clarify the parameter kind distinction between top and bottom.
| from typing import assert_never | ||
| from typing import assert_never, final | ||
|
|
||
| @final |
There was a problem hiding this comment.
Without @final, we would now reveal Box[T@box_with_default] | (T@box_with_default & Top[Box[Unknown]]) in the first isinstance branch below. I believe this is correct (and was wrong on main): it accounts for the possibility of a common subclass of str and Box (possibly with another specialization). The return value consequently lead to an error.
I added @final to restore the original intention of this test (similar in match.md).
| static_assert(not is_disjoint_from(list[list[T]], list[list[int]])) | ||
| static_assert(not is_disjoint_from(list[list[Id[T]]], list[list[int]])) | ||
| static_assert(not is_disjoint_from(list[list[T]], list[list[Never]])) |
| static_assert(not is_disjoint_from(list[list[T]], list[list[str]])) | ||
| static_assert(not is_disjoint_from(list[list[T]], list[list[Never]])) |
| static_assert(not is_disjoint_from(list[list[T]], list[list[str]])) | ||
| static_assert(not is_disjoint_from(list[list[T]], list[list[bytes]])) |
| static_assert(not is_subtype_of(Top[Box[...]], Box[P])) | ||
| static_assert(not is_subtype_of(Box[P], Bottom[Box[...]])) |
There was a problem hiding this comment.
these two fail on main
| static_assert(not is_assignable_to(Top[Box[...]], Box[P])) | ||
| static_assert(not is_assignable_to(Box[P], Bottom[Box[...]])) |
There was a problem hiding this comment.
these two fail on main
| /// Returns whether no specialization satisfying the type variables' upper bounds and | ||
| /// constraints can satisfy this constraint set. | ||
| /// | ||
| /// Unlike [`Self::is_never_satisfied`], this validates solutions against the type variables' | ||
| /// upper bounds and constraints. For example, `T = int` is not contradictory by itself, but has | ||
| /// no valid solution if `T` has an upper bound of `str`. | ||
| /// | ||
| /// If the solver reaches its computation limit, we do not know whether a valid solution exists. | ||
| /// This returns `false` in that case: stopping the search is not proof that there is no solution. | ||
| pub(crate) fn has_no_valid_solutions( | ||
| self, | ||
| db: &'db dyn Db, | ||
| env: &ProgramEnvironment<'db>, | ||
| ) -> bool { | ||
| if self.is_never_satisfied(db, env) { | ||
| return true; | ||
| } | ||
|
|
||
| let inferable = { | ||
| let storage = self.builder.storage.borrow(); | ||
| let Some(support) = storage.node_support(self.node) else { | ||
| return false; | ||
| }; | ||
| // For overlap, every mentioned type variable can choose a valid specialization. | ||
| TypeVarSet::from_typevars(db, support.iter().map(|id| storage.typevar_data(id))) | ||
| }; | ||
|
|
||
| matches!( | ||
| self.solutions(db, env, inferable), | ||
| Ok(Solutions::Unsatisfiable) | ||
| ) | ||
| } |
There was a problem hiding this comment.
Maybe if this TODO get's resolved, we won't need this function?
|
Hm, the latest ecosystem analysis found two cases (below) that should be fixed before merging. I should also check if that performance regression is real. DetailsBoth examples reproduce without strict-analysis flags.
|
|
The micro-benchmark seems suspiciously related, might be real -- and I might accept that regression in a micro-benchmark if it's in exchange for fixing this terrible TODO :) but worth seeing if we can find a way to reduce. |
Summary
ty could ignore an inferable type variable when comparing top materializations of generic types. For example, it considered
Top[list[Unknown]]to be a subtype oflist[T].Here, we remove this TODO/shortcut, so union simplification and narrowing preserve all possible alternatives. Related overlap checks and callable-parameter (
ParamSpec) comparisons are adjusted to work without it.The extra check discussed in this review comment is now unnecessary and is removed.
Related previous PR: Preserve invariant materialization constraints.
closes astral-sh/ty#4201
Ecosystem
Looks like those are new true positives in strict-mode projects.
"The stable changes are expected consequences of fixing invariant comparisons involving type variables: a top materialization such as
Top[list[Unknown]]no longer incorrectly satisfies the fixed specializationlist[T], and valid union alternatives are no longer discarded on that basis. All additions occur in projects checked with strict generic narrowing. Archinstall’s non-strict result removes an incorrectredundant-castwarning. Prefect has one secondary diagnostic replacement caused by recovery from a newly rejected assignment; it does not establish a new runtimeNonepath.The comparison adds 21 stable diagnostics and removes two, including the Prefect replacement. I found no additional semantic regression in these changes."
Test plan
New regression tests